/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.worlds;

import java.awt.AlphaComposite;
import net.worlds.ui.UI;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.Transparency;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import javax.swing.JDesktopPane;
import net.worlds.input.InputState;
import net.worlds.input.XKeyListener;
import net.worlds.input.XMouseListener;
import net.worlds.input.XMouseMotionListener;
import net.worlds.input.XMouseWheelListener;


public class GamePanel extends JDesktopPane{
    private boolean chatVisible = false;
    private boolean initialResize = false;
    private int width = 1024;
    private int viewWidth = width - 220;
    private int height = 768;
    private int viewHeight = height - 55;
    private MainView view;


    private Cursor cursor;

    private TexturePaint loadingPaint;

    private VolatileImage gbuffer;
    private Graphics2D gbufGraphics;
    private VolatileImage ubuffer;
    private Graphics2D ubufGraphics;

    protected void setStartSize(int w, int h)
    {
        this.width = w;
        this.height = h;
        setViewSize();
    }
    private void setViewSize()
    {
        viewWidth = Math.max(Main.isEditor() ? width - 220 : width, 1);
        viewHeight = Math.max(Main.isEditor() ? height - 55 : height, 1);
    }
    public void setup()
    {
        setPreferredSize(new Dimension(640, 480));
        setIgnoreRepaint(true);
        addMouseListener(new XMouseListener());
        addMouseMotionListener(new XMouseMotionListener());
        addKeyListener(new XKeyListener());
        addMouseWheelListener(new XMouseWheelListener());
        addComponentListener(new ComponentListener()
        {

            public void componentResized(ComponentEvent e) {
                if(Main.canUseTools || !initialResize)
                {
                    width = getWidth();
                    height = getHeight();
                    if(width <= 0 || height <= 0)
                        return;
                    setViewSize();
                    view.setSize(viewWidth, viewHeight);
                    rebuildImage();
                    
                    if(Main.getGame() != null && Main.getGame().getCurrentWorld() != null)
                        view.updatePaint(Main.getGame().getCurrentWorld());
                    view.updateBackground();
                    repaint();
                }
                initialResize = true;
            }

            public void componentMoved(ComponentEvent e) {

            }

            public void componentShown(ComponentEvent e) {

            }

            public void componentHidden(ComponentEvent e) {

            }

        });
    }

    public void setView(MainView v)
    {
        view = v;
    }
    public VolatileImage createCompatibleImage(int width, int height)
    {
        return Util.getGraphicsConfiguration().createCompatibleVolatileImage(width, height);
    }
    public void rebuildImage()
    {
        gbuffer = Util.getGraphicsConfiguration().createCompatibleVolatileImage(viewWidth, viewHeight, Transparency.OPAQUE);
        gbufGraphics = gbuffer.createGraphics();
        ubuffer = Util.getGraphicsConfiguration().createCompatibleVolatileImage(width, height, Transparency.TRANSLUCENT);
        ubufGraphics = ubuffer.createGraphics();
        UI.repaintUI = true;
        repaint();
    }
    public BufferedImage getImage()
    {
        BufferedImage img = new BufferedImage(gbuffer.getWidth(), gbuffer.getHeight(), BufferedImage.TYPE_INT_RGB);
        view.draw(img.createGraphics() ,gbuffer.getWidth(), gbuffer.getHeight());
        return img;
    }
    @Override
    public void paintComponent(Graphics g)
    {
        do
        {
            if(gbuffer.validate(Util.getGraphicsConfiguration()) == VolatileImage.IMAGE_INCOMPATIBLE || ubuffer.validate(Util.getGraphicsConfiguration()) == VolatileImage.IMAGE_INCOMPATIBLE)
                rebuildImage();
            if(gbufGraphics == null)
                gbufGraphics = gbuffer.createGraphics();
            if(ubufGraphics == null)
                ubufGraphics = ubuffer.createGraphics();
				
            view.draw((Graphics2D) gbufGraphics, viewWidth, viewHeight);
            g.drawImage(gbuffer, 0, Main.isEditor()?55:0, null);
            if(Main.isEditor())
            {
                if((UI.repaintUI || UI.repaintAdvancedTools || UI.menuOpen))
                {
                    ubufGraphics.setComposite(AlphaComposite.Src);
                    ubufGraphics.setColor(Util.transparent);
                    ubufGraphics.fillRect(0, 0, width, height);
                    ubufGraphics.setComposite(AlphaComposite.SrcOver);
                    view.drawUI((Graphics2D) ubufGraphics, width, height, viewWidth, viewHeight);
                    UI.repaintUI = false;
                    UI.repaintAdvancedTools = false;
                }
                g.drawImage(ubuffer, 0, 0, null);
            }
            else
            {
                view.drawUI((Graphics2D) g, width, height, viewWidth, viewHeight);
            }
        }
        while(gbuffer.contentsLost() || ubuffer.contentsLost());
    }
    @Override
    public void update(Graphics g)
    {
        paintComponent(g);
    }
    @Override
    public void addNotify() {
        super.addNotify();
        UI.viewVisible = true;
    }
    @Override
    public void setCursor(Cursor c)
    {
        cursor = c;
        if(!UI.mouseOverUI)
            super.setCursor(c);
    }
    public void mouseOverUI()
    {
        super.setCursor(Cursor.getDefaultCursor());
    }
    public void mouseOffUI()
    {
        super.setCursor(cursor);
    }
    @Override
    public int getWidth()
    {
        if(super.getWidth() <= 0)
            return width;
        else
            return super.getWidth();
    }
    @Override
    public int getHeight()
    {
        if(super.getHeight() <= 0)
            return height;
        else
            return super.getHeight();
    }
}
